/**
 * 
 */
package com.wubo.sec.acl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import com.wubo.common.util.CollectionUtils;
import com.wubo.sec.SecurityManager;
import com.wubo.sec.acl.core.AclManager;
import com.wubo.sec.bean.RoleAuthRelate;
import com.wubo.sec.core.UserData;
import com.wubo.sec.filter.AuthorityBeforeFilter;
import com.wubo.sec.model.Authority;
import com.wubo.sec.model.Role;
import com.wubo.sec.service.IAuthorityService;
import com.wubo.sec.service.IRoleService;

/**
 * @author WuBo
 * @CreateDate 2012-4-24
 */
@Component
public class RoleAuthAcl extends EntityRelateAcl {
	@Resource
	private IRoleService roleService;
	@Resource
	private IAuthorityService authService;

	public int getAcl(Object obj) {
		UserData curuser = SecurityManager.getCurrentUser();
		if(curuser == null){
			return 0;
		}
		RoleAuthRelate rar = (RoleAuthRelate) obj;
		Role role = roleService.get(rar.getRoleCode());
		int roleAcl = new RoleAcl(role).getAcl();
		if(! AclManager.getInstance().hasActions(roleAcl, "ACL_DEL")){
			return 0;
		}
		
		String[] authCodes = rar.getAuthCodes();
		if(authCodes == null || authCodes.length == 0){
			return AclManager.getInstance().getAcl("ACL_RELATE");
		}
		List<Authority> auths = new ArrayList<Authority>(curuser.getAllAuthorities());
		
		int match = match(auths, authCodes);
		
		if(match >= authCodes.length){
			return AclManager.getInstance().getAcl("ACL_RELATE");
		}
		
		auths.addAll( authService.findRunAs("where 1=1"+new AuthorityBeforeFilter().sift(), null) );
		auths = CollectionUtils.uniqueList(auths);
		
		match = match(auths, authCodes);
		if(match >= authCodes.length){
			return AclManager.getInstance().getAcl("ACL_RELATE");
		}
		return 0;
	}
	
	private int match(List<Authority> auths, String[] authCodes){
		int match = 0;
		for(Authority auth : auths){
			for(String authCode : authCodes){
				if(auth.getCode().equals(authCode)){
					match ++;
					break;
				}
			}
		}
		return match;
	}
}
